package net.xdclass.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import net.xdclass.component.StoreEngine;
import net.xdclass.controller.req.AccountLoginReq;
import net.xdclass.config.AccountConfig;
import net.xdclass.config.MinioConfig;
import net.xdclass.controller.req.AccountRegisterReq;
import net.xdclass.controller.req.FolderCreateReq;
import net.xdclass.dto.AccountDTO;
import net.xdclass.dto.StorageDTO;
import net.xdclass.enums.AccountRoleEnum;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.exception.BizException;
import net.xdclass.mapper.AccountFileMapper;
import net.xdclass.mapper.AccountMapper;
import net.xdclass.mapper.StorageMapper;
import net.xdclass.model.AccountDO;
import net.xdclass.model.AccountFileDO;
import net.xdclass.model.StorageDO;
import net.xdclass.service.AccountFileService;
import net.xdclass.service.AccountService;
import net.xdclass.utils.CommonUtil;
import net.xdclass.utils.SpringBeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private StoreEngine storeEngine;

    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private StorageMapper storageMapper;

    @Autowired
    private AccountFileService accountFileService;

    @Autowired
    private AccountFileMapper accountFileMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(AccountRegisterReq req) {

        List<AccountDO> accountDOList = accountMapper.selectList(new QueryWrapper<AccountDO>().eq("phone", req.getPhone()));
        if(!accountDOList.isEmpty()){
            throw new BizException(BizCodeEnum.ACCOUNT_REPEAT);
        }
        AccountDO accountDO = SpringBeanUtil.copyProperties(req, AccountDO.class);
        String digestAsHex = DigestUtils.md5DigestAsHex((AccountConfig.Account_SALT + req.getPassword()).getBytes());
        accountDO.setPassword(digestAsHex);
        accountDO.setRole(AccountRoleEnum.COMMON.name());
        accountMapper.insert(accountDO);

        //创建默认存储空间
        StorageDO storageDO = new StorageDO();
        storageDO.setAccountId(accountDO.getId());
        storageDO.setUseSize(0L);
        storageDO.setTotalSize(AccountConfig.Account_DEFAULT_SIZE);
        storageMapper.insert(storageDO);

        //创建根目录
        FolderCreateReq rootFolderReq = FolderCreateReq.builder()
                .accountId(accountDO.getId())
                .parentId(AccountConfig.ROOT_PARENT_ID)
                .folderName(AccountConfig.ROOT_FOLDER_NAME)
                .build();
        accountFileService.createFolder(rootFolderReq);

    }

    @Override
    public String updateAvatar(MultipartFile file) {
        String fileName = CommonUtil.getFilePath(file.getOriginalFilename());
        storeEngine.upload(minioConfig.getAvatarBucketName(), fileName,file);
        return minioConfig.getEndpoint()+"/"+minioConfig.getAvatarBucketName()+"/"+fileName;
    }

    @Override
    public AccountDTO login(AccountLoginReq req) {

        String digestAsHex = DigestUtils.md5DigestAsHex((AccountConfig.Account_SALT + req.getPassword()).getBytes());

        AccountDO accountDO = accountMapper.selectOne(new QueryWrapper<AccountDO>().eq("phone", req.getPhone()).eq("password", digestAsHex));
        if(accountDO == null){
            throw new BizException(BizCodeEnum.ACCOUNT_PWD_ERROR);
        }

        return SpringBeanUtil.copyProperties(accountDO, AccountDTO.class);
    }

    @Override
    public AccountDTO queryDetail(Long id) {
        //账号详情
        AccountDO accountDO = accountMapper.selectById(id);
        AccountDTO  accountDTO = SpringBeanUtil.copyProperties(accountDO, AccountDTO.class);

        //获取存储信息
        StorageDO storageDO = storageMapper.selectOne(new QueryWrapper<StorageDO>().eq("account_id", id));

        //获取文件信息
        AccountFileDO accountFileDO = accountFileMapper.selectOne(new QueryWrapper<AccountFileDO>().eq("account_id", id).eq("parent_id", AccountConfig.ROOT_PARENT_ID));
        accountDTO.setRootFileId(accountFileDO.getId());
        accountDTO.setRootFileName(accountFileDO.getFileName());
        accountDTO.setStorageDTO(SpringBeanUtil.copyProperties(storageDO, StorageDTO.class));
        return accountDTO ;
    }
}
